import { messages } from "share/common";
import React, { Component, PropTypes } from "react";
import { connect } from "react-redux";
import { Input, Select, Form } from "antd";
import Chooser from "components/chooser";
import Searcher from "components/searcher";
import CompactInput from "components/compact-input";
const Option = Select.Option;
const FormItem = Form.Item;

class Priority extends Component {
  state = {
    range: null,
    rangeValue: [],
    companyRange: null,
    companyValue: [],
  };

  companyValueKey = "id";
  companyLabelKey = "name";

  componentDidMount() {
    const {
      defaultValue,
      top,
      companyProps,
      onlySetOfBooks,
      onlyCompany,
      showCompany,
      tenantInfo,
      isEmptyCompanysShownAsPart,
    } = this.props;
    if (onlySetOfBooks || onlyCompany) {
      this.setState({ range: onlySetOfBooks ? "SET_OF_BOOK" : "COMPANY" });
      if (defaultValue) {
        this.setState(defaultValue);
      }
    } else {
      if (companyProps && companyProps.valueKey)
        this.companyValueKey = companyProps.valueKey;
      if (companyProps && companyProps.labelKey)
        this.companyLabelKey = companyProps.labelKey;
      if (top === "COMPANY") {
        this.setState({ range: "COMPANY" });
        if (defaultValue) {
          this.setState({
            rangeValue: [
              {
                [this.companyLabelKey]: defaultValue.levelOrgName,
                [this.companyValueKey]: defaultValue.levelOrgId,
              },
            ],
          });
        }
      } else {
        if (!showCompany) {
          if (top === "TENANT") {
            this.setState({
              range: top,
              rangeValue: [tenantInfo],
            });
          } else {
            this.setState({ range: top });
          }
        }
        if (defaultValue) {
          let companies =
            (defaultValue.distribution &&
              defaultValue.distribution.companies) ||
            [];
          if (defaultValue.levelCode === "COMPANY") {
            this.setState({
              range: "COMPANY",
              rangeValue: [
                {
                  [this.companyLabelKey]: defaultValue.levelOrgName,
                  [this.companyValueKey]: defaultValue.levelOrgId,
                },
              ],
            });
          } else {
            this.setState({
              range: top,
              rangeValue: [
                top === "TENANT"
                  ? {
                      tenantName: defaultValue.levelOrgName,
                      id: defaultValue.levelOrgId,
                    }
                  : {
                      setOfBooksName: defaultValue.levelOrgName,
                      setOfBooksId: defaultValue.levelOrgId,
                    },
              ],
              companyRange:
                companies.length === 0
                  ? isEmptyCompanysShownAsPart
                    ? "PART"
                    : "ALL"
                  : "PART",
              companyValue: companies,
            });
          }
        }
      }
    }
  }

  componentWillReceiveProps(nextProps) {
    if ("value" in nextProps) {
      const { value, onlySetOfBooks, onlyCompany } = nextProps;
      if (onlySetOfBooks || onlyCompany) {
        this.setState({
          rangeValue: value && value.rangeValue ? [value.rangeValue] : [],
        });
      }
    }
  }

  onChangeTenantRange = (range) => {
    const { tenantInfo, onChange, onChangeRange, onlyTenant } = this.props;
    this.setState(
      {
        range,
        companyValue: [],
        rangeValue: range === "TENANT" ? [tenantInfo] : [],
        companyRange: null,
      },
      () => {
        if (onlyTenant) {
          onChange({
            range,
            rangeValue: range === "TENANT" ? tenantInfo : null,
          });
        } else {
          this.setState({
            companyRange: "ALL",
            companyValue: [],
          });
          onChange(
            range === "TENANT"
              ? {
                  levelCode: "TENANT",
                  levelOrgName: tenantInfo.tenantName,
                  levelOrgId: tenantInfo.id,
                }
              : null
          );
        }
        onChangeRange(range === "TENANT" ? tenantInfo : null);
      }
    );
  };

  onChangeSetOfBooksRange = (range) => {
    const { onChange, onlySetOfBooks, onChangeRange } = this.props;
    this.setState(
      {
        range,
        companyValue: [],
        rangeValue: [],
        companyRange: null,
      },
      () => {
        onChange(
          onlySetOfBooks
            ? {
                range,
                rangeValue: null,
              }
            : null
        );
        onChangeRange(null);
      }
    );
  };

  onChangeRangeValue = (rangeValue) => {
    const { range } = this.state;
    const {
      onChange,
      onlySetOfBooks,
      onlyCompany,
      onChangeRange,
      onlyTenant,
    } = this.props;
    this.setState({ rangeValue }, () => {
      if (onlySetOfBooks || onlyCompany || onlyTenant) {
        onChange(
          rangeValue.length > 0
            ? {
                range,
                rangeValue: rangeValue[0],
              }
            : null
        );
      } else {
        if (range === "COMPANY") {
          if (rangeValue.length > 0) {
            let company = rangeValue[0];
            onChange({
              levelCode: "COMPANY",
              levelOrgName: company[this.companyLabelKey],
              levelOrgId: company[this.companyValueKey],
              companyOID: company.companyOID,
            });
          } else {
            onChange(null);
          }
        } else {
          //range不为COMPANY时只可能是选择账套
          if (rangeValue.length > 0) {
            let data = rangeValue[0];
            this.setState({
              companyRange: "ALL",
              companyValue: [],
            });
            onChange({
              levelCode: "SET_OF_BOOK",
              levelOrgName: data.setOfBooksName,
              levelOrgId: data.setOfBooksId,
            });
          } else {
            onChange(null);
          }
        }
      }
      onChangeRange(rangeValue.length > 0 ? rangeValue[0] : null);
    });
  };

  onChangeCompanyRange = (companyRange) => {
    const { top, onChange } = this.props;
    const { rangeValue } = this.state;
    this.setState({ companyRange }, () => {
      let data = rangeValue[0];
      if (companyRange === "ALL") {
        onChange({
          levelCode: top,
          levelOrgName:
            top === "TENANT" ? data.tenantName : data.setOfBooksName,
          levelOrgId: top === "TENANT" ? data.id : data.setOfBooksId,
        });
      } else {
        onChange({
          levelCode: top,
          levelOrgName:
            top === "TENANT" ? data.tenantName : data.setOfBooksName,
          levelOrgId: top === "TENANT" ? data.id : data.setOfBooksId,
          distribution: {
            companies: [],
          },
        });
      }
    });
  };

  onChangeCompanyValue = (companyValue) => {
    const { onChange, top } = this.props;
    const { rangeValue } = this.state;
    this.setState({ companyValue }, () => {
      let data = rangeValue[0];
      onChange({
        levelCode: top,
        levelOrgName: top === "TENANT" ? data.tenantName : data.setOfBooksName,
        levelOrgId: top === "TENANT" ? data.id : data.setOfBooksId,
        distribution: {
          companies: companyValue.map((company) => ({
            [this.companyLabelKey]: company[this.companyLabelKey],
            [this.companyValueKey]: company[this.companyValueKey],
          })),
        },
      });
    });
  };

  getComponentProps = (type, disabledTop) => {
    const { tenantInfo, top, showCompany, disabled, isOldCompany } = this.props;
    let prevComponent = null;
    let nextComponent = null;
    const { range, rangeValue, companyRange, companyValue } = this.state;
    let companyOption = {
      label: messages("common-1.key423") /*公司*/,
      value: "COMPANY",
    };
    switch (type) {
      case "TENANT":
        let options = [
          {
            label: messages("common-1.key424") /*租户*/,
            value: "TENANT",
          },
        ];
        showCompany && options.push(companyOption);
        prevComponent = (
          <Select
            value={range}
            onChange={this.onChangeTenantRange}
            disabled={disabled || disabledTop}
          >
            {options.map((option) => (
              <Option key={option.value}>{option.label}</Option>
            ))}
          </Select>
        );
        nextComponent =
          range === "COMPANY" ? (
            this.createCompanyComponent()
          ) : (
            <Input
              disabled
              value={range === "TENANT" ? tenantInfo.tenantName : ""}
            />
          );
        break;
      case "SET_OF_BOOK":
        console.log({range})
        let option = [
          {
            label: messages("common-1.key425") /*账套*/,
            value: "SET_OF_BOOK",
          },
        ];
        showCompany && option.push(companyOption);
        prevComponent = (
          <Select
            value={range}
            onChange={this.onChangeSetOfBooksRange}
            disabled={disabled || disabledTop}
          >
            {option.map((option) => (
              <Option key={option.value}>{option.label}</Option>
            ))}
          </Select>
        );
        nextComponent =
          range === "COMPANY" ? (
            this.createCompanyComponent()
          ) : (
            <Chooser
              value={rangeValue}
              disabled={disabled || range === null || disabledTop}
              single
              type="select_set_of_books"
              labelKey="setOfBooksName"
              valueKey="setOfBooksId"
              onChange={this.onChangeRangeValue}
            />
          );
        break;
      case "ONLY_COMPANY":
        prevComponent = (
          <Select value="COMPANY" disabled={disabled}>
            <Option value="COMPANY">
              {messages("common-1.key423") /*公司*/}
            </Option>
          </Select>
        );
        nextComponent = this.createCompanyComponent();
        break;
      case "COMPANY":
        prevComponent = (
          <Select
            value={companyRange}
            onChange={this.onChangeCompanyRange}
            disabled={disabled || disabledTop}
          >
            {[
              {
                label: messages("common.all") /*全部*/,
                value: "ALL",
              },
              {
                label: messages("common-1.key426") /*部分*/,
                value: "PART",
              },
            ].map((option) => (
              <Option key={option.value}>{option.label}</Option>
            ))}
          </Select>
        );
        const { getSetOfBooksCompanyParams } = this.props;
        if (companyRange !== "ALL") {
          let setOfBooksParams =
            rangeValue.length > 0
              ? getSetOfBooksCompanyParams(rangeValue[0].setOfBooksId)
              : {};
          nextComponent = React.cloneElement(
            this.createCompanyComponent(),
            {
              disabled: companyRange !== "PART" || disabled || disabledTop,
              listExtraParams: top === "SET_OF_BOOK" ? setOfBooksParams : {},
              onChange: this.onChangeCompanyValue,
              value: companyValue,
              single: false,
            },
            null
          );
        } else {
          nextComponent = (
            <Input disabled value={messages("common-1.key421") /*通用*/} />
          );
        }
        break;
    }
    return [prevComponent, nextComponent];
  };

  componentMap = {
    Chooser,
    Searcher,
  };

  createCompanyComponent = () => {
    const {
      companyComponent,
      companyProps,
      disabled,
      isOldCompany,
    } = this.props;
    const { rangeValue } = this.state;
    let props = {
      value: rangeValue,
      labelKey: "name",
      valueKey: "id",
      descriptionKey: "companyCode",
      onChange: this.onChangeRangeValue,
      type: "priority_company",
      single: true,
      disabled,
    };
    return React.createElement(
      this.componentMap[companyComponent],
      Object.assign({}, props, companyProps),
      null
    );
  };

  renderFormItem = (type, disabledTop) => {
    const [prevComponent, nextComponent] = this.getComponentProps(
      type,
      disabledTop
    );
    return (
      <CompactInput>
        {prevComponent}
        {nextComponent}
      </CompactInput>
    );
  };

  render() {
    const {
      top,
      formItemLayout,
      onlyTenant,
      onlySetOfBooks,
      required,
      onlyCompany,
      disabledTop,
      showCompanyComponent,
      showLabel,
    } = this.props;
    const { range, rangeValue } = this.state;
    if (onlySetOfBooks) {
      return (
        <div className="priority">{this.renderFormItem("SET_OF_BOOK")}</div>
      );
    } else if (onlyCompany) {
      return (
        <div className="priority">{this.renderFormItem("ONLY_COMPANY")}</div>
      );
    } else if (onlyTenant) {
      return <div className="priority">{this.renderFormItem("TENANT")}</div>;
    }
    {
      if (top === "COMPANY")
        return (
          <div className="priority">
            <FormItem
              {...formItemLayout}
              label={showLabel ? messages("common-1.key427") /*所属组织*/ : ""}
              required={required}
            >
              {this.renderFormItem("ONLY_COMPANY")}
            </FormItem>
          </div>
        );
      else {
        let needCompany = false;
        if (range === top) {
          if (range === "TENANT") needCompany = true;
          else if (rangeValue.length > 0) needCompany = true;
        }
        return (
          <div className="priority">
            <FormItem
              {...formItemLayout}
              label={showLabel ? messages("common-1.key427") /*所属组织*/ : ""}
              required={required}
            >
              {this.renderFormItem(top, disabledTop)}
            </FormItem>
            {needCompany && showCompanyComponent && (
              <FormItem
                {...formItemLayout}
                label={messages("common-1.key428") /*启用公司*/}
                required={required}
              >
                {this.renderFormItem("COMPANY")}
              </FormItem>
            )}
          </div>
        );
      }
    }
  }

  static propTypes = {
    formItemLayout: PropTypes.object,
    top: PropTypes.oneOf(["TENANT", "SET_OF_BOOK", "COMPANY"]),
    onChange: PropTypes.func,
    defaultValue: PropTypes.object,
    companyComponent: PropTypes.oneOf(["Chooser", "Searcher"]), //想改成ProTypes.node,但是外面调用就很麻烦，还是用这个吧
    companyProps: PropTypes.object,
    getSetOfBooksCompanyParams: PropTypes.func,
    disabled: PropTypes.bool,
    onlySetOfBooks: PropTypes.bool,
    onlyCompany: PropTypes.bool,
    onlyTenant: PropTypes.bool,
    showCompany: PropTypes.bool,
    showCompanyComponent: PropTypes.bool,
    disabledTop: PropTypes.bool,
    onChangeRange: PropTypes.func,
    showLabel: PropTypes.bool,
    required: PropTypes.bool,
    isEmptyCompanysShownAsPart: PropTypes.bool, // 当选择的公司为空时，是否显示为部分，正常逻辑为全部
  };

  static defaultProps = {
    formItemLayout: {
      labelCol: { span: 8 },
      wrapperCol: { span: 10, offset: 1 },
    },
    onChange: () => {},
    companyComponent: "Chooser",
    companyProps: {},
    getSetOfBooksCompanyParams: (setOfBooksId) => ({ setOfBooksId }),
    showCompany: true,
    showCompanyComponent: true,
    onChangeRange: () => {},
    showLabel: true,
    isEmptyCompanysShownAsPart: false,
  };
}

function mapStateToProps(state) {
  return {
    isOldCompany: state.login.isOldCompany,
    tenantInfo: state.login.tenant,
  };
}

export default connect(mapStateToProps)(Priority);
